﻿using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Ext.Direct.Mvc
{
    internal class DirectAction
    {
        private readonly IDictionary<string, DirectMethod> _methods;

        internal DirectAction(Type type) {
            this.Name = type.Name;
            if (this.Name.EndsWith("Controller")) {
                this.Name = this.Name.Substring(0, this.Name.IndexOf("Controller"));
            }
            _methods = new Dictionary<string, DirectMethod>();
            ConfigureMethods(type);
        }

        internal string Name {
            get;
            private set;
        }

        // Adds class methods (controller actions) to the internal collection
        private void ConfigureMethods(Type type) {
            var methods = type.GetMethods();
            foreach (var method in methods) {
                if (DirectMethod.IsDirectMethod(method)) {
                    _methods.Add(method.Name, new DirectMethod(method));
                }
            }
        }

        internal DirectMethod GetMethod(string name) {
            if (!_methods.ContainsKey(name)) {
                return null;
            }
            return _methods[name];
        }
        // Writes JSON representaion of the action to the specified JsonWriter.
        // Used to generate Ext.Direct API
        internal void WriteJson(JsonWriter jsonWriter) {
            jsonWriter.WritePropertyName(Name);
            jsonWriter.WriteStartArray();
            foreach (var method in _methods.Values) {
                method.WriteJson(jsonWriter);
            }
            jsonWriter.WriteEndArray();
        }

        // Checks whether a class is a Direct action, e.g. inherits from DirectController
        internal static bool IsDirectAction(Type type) {
            bool isDirectController = type.IsSubclassOf(typeof(DirectController));
            bool ignore = type.GetCustomAttributes(typeof(DirectIgnoreAttribute), true).Length > 0;
            return (isDirectController && !ignore);
        }
    }
}
